package com.tong.hao.batch.config;

import com.tong.hao.batch.listener.ThJobListener;
import com.tong.hao.batch.listener.ThStepListener;
import com.tong.hao.batch.step.test.StringProcessor;
import com.tong.hao.batch.step.test.StringReader;
import com.tong.hao.batch.step.test.StringWriter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ClassName ThBatchConfig
 * @Author 友野浩二
 * @Date 2019/11/25 22:59
 * @Description 任务组装
 * @Version 1.0
 *
 * <pre>
 *     经过Step的读取、处理、写入以及Job完成后的监听操作,需要将这些都组装在一起,形成一个完整的任务。
 *
 *     @Configuration : 用于定义配置类，可替换xml配置文件，被注解的类内部包含有一个或多个被@Bean注解的方法，
 *                      这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描，
 *                      并用于构建bean定义，初始化Spring容器。
 *     @EnableBatchProcessing : 启用Spring Batch
 * </pre>
 */
@Configuration
@EnableBatchProcessing
@Slf4j
public class ThBatchConfig {

    /**
     * 创建Job
     */
    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    /**
     * 创建Step
     */
    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    public ThBatchConfig() {
        log.info("Th Batch Start, create com.tong.hao.batch.config.ThBatchConfig");
    }

    /**
     * @return org.springframework.batch.item.ItemReader
     * @Author 友野浩二
     * @Description // 数据读取阶段ItemReader
     * @Date 2019/11/25 13:15
     * @Param []
     **/
    @Bean
    public StringReader stringReader() {
        return new StringReader();
    }

    /**
     * @return org.springframework.batch.item.ItemProcessor
     * @Author 友野浩二
     * @Description // 数据处理阶段ItemProcessor
     * @Date 2019/11/25 13:16
     * @Param []
     **/
    @Bean
    public StringProcessor stringProcessor() {
        return new StringProcessor();
    }

    /**
     * @return org.springframework.batch.item.ItemWriter
     * @Author 友野浩二
     * @Description // 数据写入阶段ItemWriter
     * @Date 2019/11/25 13:16
     * @Param []
     **/
    @Bean
    public StringWriter stringWriter() {
        return new StringWriter();
    }

    /**
     * @return com.tong.hao.batch.listener.ThStepListener
     * @Author 友野浩二
     * @Description // Step监听器
     * @Date 2019/11/25 23:50
     * @Param []
     **/
    @Bean
    public ThStepListener thStepListener() {
        return new ThStepListener();
    }

    @Bean
    public Step thStep(StringReader stringReader, StringProcessor stringProcessor, StringWriter stringWriter,
                       ThStepListener thStepListener) {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        // 创建作业step,其中chunk面向块的处理,即多次读取后再写入,提高效率
        return this.stepBuilderFactory.get(methodName).listener(thStepListener)
                .<String, String>chunk(3).reader(stringReader).processor(stringProcessor).writer(stringWriter).build();
    }

    /**
     * @return com.tong.hao.batch.listener.ThJobListener
     * @Author 友野浩二
     * @Description // Job监听器
     * @Date 2019/11/25 16:14
     * @Param []
     **/
    @Bean
    public ThJobListener thJobListener() {
        return new ThJobListener();
    }

    @Bean
    public Job thJob(Step thStep, ThJobListener thJobListener) {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        // 创建Job,添加step
        return this.jobBuilderFactory.get(methodName).listener(thJobListener).flow(thStep).end().build();
    }

}
